//////////////////////////////////////////////////////////////////////////////////
// Module: z80_reg
// This module implements a simple APB (Advanced Peripheral Bus) register block
// for Z80-related control or configuration registers.
//////////////////////////////////////////////////////////////////////////////////

module z80_reg #(
    parameter ADDR = 24'b000000
)(
    input  wire             clk,                    // Bus clock
    input  wire             rst_n,                  // System reset
    input  wire             apb_psel_in,
    input  wire             apb_penable_in,
    input  wire             apb_pwrite_in,
    input  wire [31:0]      apb_paddr_in,
    input  wire [31:0]      apb_pwdata_in,
    output wire [31:0]      data_out,
    output wire             apb_pready_out
);

reg [31:0] data_out_reg;
reg        apb_pready_out_reg;

// Write operation: update the external register in ACCESS phase
always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        data_out_reg <= 32'b0;
    end
    else begin
        // APB write.
        if (apb_psel_in && (apb_paddr_in[23:0] == ADDR)) begin
            if(~apb_penable_in) begin
                apb_pready_out_reg <= 1'b0;
            end
            else begin
                apb_pready_out_reg <= 1'b1;
                if(apb_pwrite_in) begin
                    data_out_reg <= apb_pwdata_in;
                end
            end
        end
        // Idle.
        else begin
            apb_pready_out_reg <= 1'b1;
        end
    end
end

assign data_out       = data_out_reg;
assign apb_pready_out = apb_pready_out_reg;

endmodule